package org.zero.onlinesubject.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mysql.cj.util.StringUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zero.onlinesubject.common.constant.RedisConstant;
import org.zero.onlinesubject.common.vo.Result;
import org.zero.onlinesubject.common.vo.UserVo;
import org.zero.onlinesubject.common.vo.WxUserInfo;
import org.zero.onlinesubject.common.vo.WxUserVo;
import org.zero.onlinesubject.entity.User;
import org.zero.onlinesubject.service.UserService;
import org.zero.onlinesubject.service.impl.QrService;
import org.zero.onlinesubject.service.impl.ThreadService;
import org.zero.onlinesubject.utils.JwtUtil;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.concurrent.*;

@RestController
@RequestMapping("/wx/api")
public class WxAuthController {

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private QrService qrService;

    @Resource
    private UserService userService;

    @Resource
    private ThreadService threadService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private Executor taskExecutor;

    @GetMapping("/wxCallback")
    public String getUserInfo(String code,String state) {
        if(state==null){
            return "请求失败";
        }
        WxUserInfo userInfo = qrService.getUserInfo(code,state);

        User user = new User();
        user.setUserid(userInfo.getOpenid());
        user.setAvatar(userInfo.getHeadimgurl());
        user.setUsername(userInfo.getNickname());
        user.setRegisterdate(LocalDateTime.now());
        user.setRoleid(5);
        user.setLearnCount(0);

        threadService.saveUserInfo(userService,user);

        String token = jwtUtil.createToken(userInfo.getOpenid());
        stringRedisTemplate.opsForValue().set(RedisConstant.WX_CODE_PREFIX+state,token,5, TimeUnit.MINUTES);
        String html = "<!DOCTYPE html>" +
                "<html lang=\"en\">" +
                "<head>" +
                "<meta charset=\"UTF-8\">" +
                "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" +
                "<title>登录成功</title>" +
                "<style>" +
                "body{" +
                "width: 100vw;" +
                "height: 100vh;" +
                "background-color: #fbfbfb;" +
                "}" +
                "</style>" +
                "</head>" +
                "<body>" +
                "<img src='http://122.152.235.2/pic/success.png' width='800px' height='800px'" +
                "style='display:block;margin: 100px auto;' />" +
                "</body>" +
                "</html>";
        return html;
    }

    @GetMapping("/getQr")
    public Result<String> getQr(String uuid) {
        String qrCode = qrService.getQRCode(uuid);
        System.out.println(qrCode);
        return Result.ok("获取二维码成功",qrCode);
    }

    // 这个接口在一分钟内会被轮询访问，用于询问用户是否登录
    @GetMapping("/isAuth")
    public Result<WxUserVo> isAuth(String uuid){
        String token = stringRedisTemplate.opsForValue().get(RedisConstant.WX_CODE_PREFIX + uuid);
        if(StringUtils.isNullOrEmpty(token)){
            return Result.error(500,"用户未认证");
        }
        Claims claim = jwtUtil.parseToken(token);
        String userId = claim.getId();
        CompletableFuture<UserVo> f1 = CompletableFuture.supplyAsync(() -> {
            UserVo userVo = userService.getUserVo(userId);

            User user = new User();
            BeanUtils.copyProperties(userVo, user);
            user.setRoleid(userVo.getRole().getRoleid());
            stringRedisTemplate.opsForValue().set(RedisConstant.TOKEN_PREFIX + userId, JSON.toJSONString(user), 2, TimeUnit.HOURS);
            return userVo;
        }, taskExecutor);

        CompletableFuture<Boolean> f2 = CompletableFuture.supplyAsync(() -> {
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.select("Password").eq("UserID", userId).last(" limit 1");
            User user = userService.getOne(wrapper);
            if (user != null && !StringUtils.isNullOrEmpty(user.getPassword())) {
                return false;
            }
            return true;
        }, taskExecutor);

        WxUserVo vo = new WxUserVo();
        try {
            CompletableFuture.allOf(f1,f2).get(3,TimeUnit.SECONDS);
            vo.setUserVo(f1.get());
            vo.setToken(token);
            vo.setNeedPass(f2.get());
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            e.printStackTrace();
        }
        return Result.ok(vo);
    }

    // 给微信用户添加密码
    @PostMapping("/addPass")
    public Result<String> addPass(String pwd){
        Boolean flag = userService.pwdChange(pwd);
        return flag ? Result.ok("绑定密码成功") : Result.error(500,"绑定密码失败");
    }
}
